home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 8 / FM Towns Free Software Collection 8.iso / t_os / otohime / src / lib / vchan.asm < prev    next >
Assembly Source File  |  1994-06-01  |  12KB  |  618 lines

  1. ;            VOICE CHANGER
  2. ;
  3. ;        call from F-BASIC386 or High C
  4. ;    callm address,varptr(source),varptr(new),varptr(param),varptr(work)
  5. ;    void  VCHAN(*sourcesnd,*newsnd,*param,*work)
  6. ;
  7. ;
  8. ;            1990 3  Hiroshi TODA
  9. ;
  10. ;            1993 12 High C 用に改造
  11. ;
  12. ;    param: cycle , mode*10000H
  13. ;    work area = 256Byte
  14. ;
  15. ;
  16.  
  17.     .386p
  18.  
  19.  
  20. param    struc
  21.  
  22.     dd    ?
  23.     dd    ?
  24. source    dd    ?        ; source snd.data address
  25. new    dd    ?        ; new snd.data address
  26. paradd    dd    ?        ; param. address
  27. wadd    dd    ?         ; work address
  28.  
  29. param   ends
  30.  
  31. work    struc
  32.  
  33. ;data area
  34.  
  35. cycle    dd    ?        ; cycle
  36. mode    dd    ?        ; rate
  37.  
  38. ;work area
  39.  
  40. point    dd    ?        ; ov.sampling point (decimal)
  41.     dd    ?        ; ov.sampling point (integer)
  42. rate    dd    ?        ; add (decimal)
  43.     dd    ?        ; add (integer)
  44. rend    dd    ?        ; read end
  45.  
  46. rated    dd    ?        ; add rate
  47. ratea    dd    ?        ; add buf.
  48. pbuf    dd    ?        ; point buf. (decimal)
  49.     dd    ?        ; point buf. (integer)
  50. count1    dd    ?        ; cycle count
  51. count2    dd    ?        ; cycle*10000H
  52.  
  53. work    ends
  54.  
  55. cseg    segment    dword public use32 'CODE'
  56.     assume    cs:cseg,ds:cseg
  57.  
  58.     public    sndVoiceChange
  59.     db    'sndVoiceGhange',14
  60. sndVoiceChange    proc    near
  61.     push    ebp
  62.     mov    ebp,esp
  63.     push    esi
  64.     push    edi
  65.     push    ebx
  66.  
  67.     mov    esi,[ebp].wadd        ; esi <-- work area top add
  68.     mov    ecx,[ebp].paradd    ; ecx <-- para. add.
  69.     xor    edx,edx            ; edx=count
  70. main01:    mov    eax,[ecx][edx*4]    ; para. --> work area
  71.     mov    [esi][edx*4],eax
  72.     inc    edx
  73.     cmp    edx,2
  74.     jb    main01
  75.  
  76.     mov    ebx,[ebp].source    ; ebx <-- source snd. add.
  77.     mov    edi,[ebp].new        ; edi <-- new snd. add.
  78.     xor    edx,edx            ; head trans
  79. main02:    mov    eax,[ebx][edx*4]
  80.     mov    [edi][edx*4],eax
  81.     inc    edx
  82.     cmp    edx,8
  83.     jb    main02
  84.  
  85.     mov    ecx,[ebx+12]        ; ecx <-- length
  86.     mov    [esi].rend,ecx
  87.     cmp    ecx,0
  88.     je    mainE
  89.     add    ebx,32            ; add head(32Byte)
  90.     add    edi,32
  91.     add    [esi].rend,ebx
  92.     sub    [esi].rend,1
  93.  
  94.     mov    eax,[esi].cycle        ; count set
  95.     cmp    eax,0
  96.     jne    main00
  97.     mov    eax,1
  98.     mov    [esi].cycle,eax
  99. main00:    mov    [esi].count1,eax
  100.     xor    edx,edx            ; set data
  101.     mov    [esi].point,edx
  102.     mov    [esi].ratea,edx
  103.     mov    eax,[esi].mode
  104.     shld    edx,eax,16
  105.     shl    eax,16
  106.     mov    [esi].rate,eax
  107.     mov    [esi].rate+4,edx
  108.     cmp    edx,0
  109.     je    main03
  110.     mov    eax,[esi].mode        ; hi
  111.     sub    eax,10000H
  112.     mov    [esi].rated,eax
  113.     mov    eax,[esi].cycle        ; set count2
  114.     shl    eax,16
  115.     mov    [esi].count2,eax
  116.     jmp    main04
  117. main03:    mov    eax,10000H
  118.     sub    eax,[esi].mode
  119.     mov    [esi].rated,eax
  120.     mov    eax,10000H        ; set count2
  121.     sub    eax,[esi].rated
  122.     mul    dword ptr [esi].cycle
  123.     mov    [esi].count2,eax
  124.  
  125. main04:    mov    al,[ebx]        ; trans while zero
  126.     mov    [edi],al
  127.     inc    ebx
  128.     inc    edi
  129.     dec    ecx
  130.     je    mainE
  131.     and    al,7fH
  132.     je    main04
  133.     dec    ebx
  134.     dec    edi
  135.     inc    ecx
  136.     mov    [esi].point+4,ebx
  137.     xor    eax,eax
  138.     add    eax,dword ptr [esi].rate+4
  139.     je    main05
  140.     call    hi
  141.     jmp    mainE
  142. main05:    call    lw
  143.  
  144. mainE:
  145.     pop    ebx
  146.     pop    edi
  147.     pop    esi
  148.     mov    esp,ebp
  149.     pop    ebp
  150.     ret
  151.  
  152.  
  153. hi:    lea    eax,[esi].point
  154.     call    smp            ; ov.smp.
  155.     call    wr            ; write
  156.     dec    ecx
  157.     je    hiE
  158.  
  159. ;    mov    ax,[edi-2]        ; cross check
  160. ;    cmp    ax,8080H
  161. ;    je    hi00
  162. ;    and    eax,8080H
  163. ;    cmp    eax,80H
  164.  
  165.     call    close_ck
  166.  
  167.     jne    hi03
  168. hi00:    mov    eax,[esi].rated        ; ratea=ratea+rated
  169.     add    [esi].ratea,eax
  170. hi01:    mov    eax,[esi].ratea
  171.     cmp    eax,[esi].count2
  172.     jb    hi03
  173.     sub    eax,[esi].count2    ; make wave
  174.     mov    [esi].ratea,eax
  175.     mov    eax,[esi].point        ; point -> buf.
  176.     mov    edx,[esi].point+4
  177.     mov    [esi].pbuf,eax
  178.     mov    [esi].pbuf+4,edx
  179.     mov    eax,[esi].cycle        ; set cycle count
  180.     mov    [esi].count1,eax
  181. hi02:    call    adp            ; loop start
  182.     lea    eax,[esi].point
  183.     call    smp
  184.     call    wr
  185.     dec    ecx
  186.     je    hiE
  187.  
  188. ;    mov    ax,[edi-2]
  189. ;    cmp    ax,8080H
  190. ;    je    hi0A
  191. ;    and    eax,8080H
  192. ;    cmp    eax,80H
  193.  
  194.     call    close_ck
  195.  
  196.     jne    hi02            ; loop end
  197. hi0A:    dec    dword ptr [esi].count1    ; cycle count
  198.     jne    hi02
  199.     mov    eax,[esi].pbuf        ; buf. -> point
  200.     mov    edx,[esi].pbuf+4
  201.     mov    [esi].point,eax
  202.     mov    [esi].point+4,edx
  203.     dec    edi            ; 1Byte over write
  204.  
  205.     ; 継ぎ接ぎを滑らかにする 1994 1
  206.  
  207.     dec edi
  208.     call    red_m_o
  209.     sar        eax,2    ; 読んだデータを1/4に
  210.     call    wr        ; 半分にして書き直し( ここで inc edi してる)
  211.  
  212.     lea    eax,[esi].point
  213.     call    smp
  214.     sar        eax,2    ; 1/4に
  215.     call    wr
  216.  
  217.     jmp    hi01
  218. hi03:    call    adp
  219.     jmp    hi
  220. hiE:    ret
  221.  
  222. lw:    lea    eax,[esi].point
  223.     call    smp            ; ov.smp.
  224.     call    wr            ; write
  225.     dec    ecx
  226.     je    lwE
  227.  
  228. ;    mov    ax,[edi-2]        ; cross check
  229. ;    cmp    ax,8080H
  230. ;    je    lw00
  231. ;    and    eax,8080H
  232. ;    cmp    eax,80H
  233.  
  234.     call    close_ck
  235.  
  236.     jne    lw03
  237. lw00:    mov    eax,[esi].rated        ; ratea=ratea+rated
  238.     add    [esi].ratea,eax
  239. lw01:    mov    eax,[esi].ratea
  240.     cmp    eax,[esi].count2
  241.     jb    lw03
  242.     sub    eax,[esi].count2    ; delete wave
  243.     mov    [esi].ratea,eax
  244.     mov    [esi].pbuf,ecx        ; count(ecx,edi) -> buf.
  245.     mov    [esi].pbuf+4,edi
  246.     mov    eax,[esi].cycle        ; set cycle count
  247.     mov    [esi].count1,eax
  248. lw02:    call    adp            ; loop start
  249.     lea    eax,[esi].point
  250.     call    smp
  251.     call    wr
  252.     dec    ecx
  253.     je    lwE
  254.  
  255. ;    mov    ax,[edi-2]
  256. ;    cmp    ax,8080H
  257. ;    je    lw0A
  258. ;    and    eax,8080H
  259. ;    cmp    eax,80H
  260.  
  261.     call    close_ck
  262.  
  263.     jne    lw02            ; loop end
  264. lw0A:    dec    dword ptr [esi].count1    ; cycle count
  265.     jne    lw02
  266.     mov    ecx,[esi].pbuf        ; buf. -> count(ecx,edi)
  267.     mov    edi,[esi].pbuf+4
  268.     dec    edi            ; 1Byte over write
  269.  
  270.     ; 継ぎ接ぎを滑らかにする 1994 1
  271.  
  272.     dec edi
  273.     call    red_m_o
  274.     sar        eax,2    ; 読んだデータを1/4に
  275.     call    wr        ; 半分にして書き直し( ここで inc edi してる)
  276.  
  277.     lea    eax,[esi].point
  278.     call    smp
  279.     sar        eax,2    ; 1/4に
  280.     call    wr
  281.  
  282.     jmp    lw01
  283. lw03:    call    adp
  284.     jmp    lw
  285. lwE:    ret
  286.  
  287.  
  288. ; 出来上がったデータを読む
  289.  
  290. red_m_o:    mov    al,[edi-1]        ; read
  291.     and    eax,0ffH
  292.     cmp    eax,128
  293.     jb    red01
  294.     mov    edx,eax
  295.     mov    eax,128
  296.     sub    eax,edx
  297. red01:    ret
  298.  
  299. ;    edi-4を境にクロスしてるかをフィルタ(平均化)にかけて判断
  300. ;    eax = 0ならクロス, eax != 0ならノンクロス
  301.  
  302. close_ck:
  303.     push    ecx
  304.     push    edx
  305.  
  306. ;    mov        eax,[edi-8]
  307.     mov        edx,[esi].(point+4)        ; オリジナルのデータを見るように変更
  308.     mov        eax,[edx-2]
  309.  
  310.     shld    edx,eax,8
  311.     cmp        dl,80h
  312.     jb        cls00
  313.     mov        dh,dl
  314.     mov        dl,80h
  315.     sub        dl,dh
  316. cls00:
  317.     movsx    edx,dl
  318.     mov        ecx,edx
  319.  
  320.     shld    edx,eax,16
  321.     cmp        dl,80h
  322.     jb        cls01
  323.     mov        dh,dl
  324.     mov        dl,80h
  325.     sub        dl,dh
  326. cls01:
  327.     movsx    edx,dl
  328. ;    shl        edx,2
  329.     add        ecx,edx
  330.  
  331.     shld    edx,eax,24
  332.     cmp        dl,80h
  333.     jb        cls02
  334.     mov        dh,dl
  335.     mov        dl,80h
  336.     sub        dl,dh
  337. cls02:
  338.     movsx    edx,dl
  339. ;    shl        edx,2
  340.     add        ecx,edx
  341.  
  342.     shld    edx,eax,32
  343.     cmp        dl,80h
  344.     jb        cls03
  345.     mov        dh,dl
  346.     mov        dl,80h
  347.     sub        dl,dh
  348. cls03:
  349.     movsx    edx,dl
  350.     add        ecx,edx
  351.  
  352.     cmp        ecx,0
  353.     jg        cls_no
  354.  
  355. ;    mov        eax,[edi-4]
  356.     mov        edx,[esi].(point+4)        ; オリジナルのデータを見るように変更
  357.     mov        eax,[edx-1]
  358.  
  359.     shld    edx,eax,8
  360.     cmp        dl,80h
  361.     jb        cls10
  362.     mov        dh,dl
  363.     mov        dl,80h
  364.     sub        dl,dh
  365. cls10:
  366.     movsx    edx,dl
  367.     mov        ecx,edx
  368.  
  369.     shld    edx,eax,16
  370.     cmp        dl,80h
  371.     jb        cls11
  372.     mov        dh,dl
  373.     mov        dl,80h
  374.     sub        dl,dh
  375. cls11:
  376.     movsx    edx,dl
  377. ;    shl        edx,2
  378.     add        ecx,edx
  379.  
  380.     shld    edx,eax,24
  381.     cmp        dl,80h
  382.     jb        cls12
  383.     mov        dh,dl
  384.     mov        dl,80h
  385.     sub        dl,dh
  386. cls12:
  387.     movsx    edx,dl
  388. ;    shl        edx,2
  389.     add        ecx,edx
  390.  
  391.     shld    edx,eax,32
  392.     cmp        dl,80h
  393.     jb        cls13
  394.     mov        dh,dl
  395.     mov        dl,80h
  396.     sub        dl,dh
  397. cls13:
  398.     movsx    edx,dl
  399.     add        ecx,edx
  400.  
  401.     cmp        ecx,0
  402.     jl        cls_no
  403.  
  404.     xor        eax,eax
  405.     jmp        cls_end
  406.  
  407. cls_no:
  408.     xor        eax,eax
  409.     sub        eax,1
  410.  
  411. cls_end:
  412.     pop        edx
  413.     pop        ecx
  414.     ret
  415.  
  416.  
  417. ;    POINT=POINT+RATE
  418.  
  419. adp:    push    eax
  420.     push    edx
  421.     mov    eax,[esi].point
  422.     mov    edx,[esi].point+4
  423.     add    eax,[esi].rate
  424.     adc    edx,[esi].rate+4
  425.     cmp    edx,[esi].rend
  426.     jb    adp01
  427.     xor    eax,eax
  428.     mov    edx,[esi].rend
  429. adp01:    mov    [esi].point,eax
  430.     mov    [esi].point+4,edx
  431.     pop    edx
  432.     pop    eax
  433.     ret
  434.  
  435. ;    WRITE DATA
  436. ;    eax -> pcm data -> [edi] & inc edi
  437.  
  438. wr:    cmp    eax,0            ; write
  439.     js    wr01
  440.     je    wr01
  441.     cmp    eax,128            ; +
  442.     jb    wr02
  443.     mov    eax,127
  444.     jmp    wr02
  445. wr01:    mov    edx,eax            ; -
  446.     mov    eax,128
  447.     sub    eax,edx
  448.     cmp    eax,256-1    ; data255はloopStopの意味があるから除外 1993 12
  449.     jb    wr02
  450.     mov    eax,255-1    ; data255はloopStopの意味があるから除外 1993 12
  451. wr02:    mov    [edi],al
  452.     inc    edi
  453.     ret
  454.  
  455. ;    OVER SAMPLING for PCM DATA(8bit)
  456. ;input    eax = 64bit(32bit/decimal,32bit/integer) data address(ds:)
  457. ;output    eax = over sampring data ( 32bit sign (-128 -- +127) )
  458.  
  459. smp:    push    ebx
  460.     push    ecx
  461.     push    edx
  462.     push    esi
  463.     push    edi
  464.     mov    ebx,[eax]        ; ebx = decimal
  465.     mov    esi,[eax+4]        ; esi = integer
  466.     shr    ebx,24            ; ebx --> 8bit
  467.     jne    smp00
  468.  
  469.     mov    al,[esi]        ; decimal=0
  470.     and    eax,0ffH
  471.     cmp    eax,128
  472.     jb    smp0A
  473.     mov    edx,eax
  474.     mov    eax,128
  475.     sub    eax,edx
  476. smp0A:    jmp    smp06
  477.  
  478. smp00:
  479.     mov    eax,[esi-1]        ; 周囲がみな無信号ならノイズを出さないよう直接0を返す
  480.     cmp    eax,80808080h
  481.     jne    smp0B
  482.     xor    eax,eax
  483.     jmp    smp06
  484.  
  485. smp0B:
  486.     call    smp01
  487. smp01:    pop    edi
  488.     add    edi,smptb-smp01        ; edi = table point
  489.  
  490.     mov    al,[esi]
  491.     and    eax,0ffH
  492.     cmp    eax,128
  493.     jb    smp02
  494.     mov    edx,eax
  495.     mov    eax,128
  496.     sub    eax,edx
  497. smp02:    add    eax,128
  498.     mul    byte ptr cs:[edi][ebx]
  499.     mov    ecx,eax
  500.  
  501.     mov    al,[esi-1]
  502.     and    eax,0ffH
  503.     cmp    eax,128
  504.     jb    smp03
  505.     mov    edx,eax
  506.     mov    eax,128
  507.     sub    eax,edx
  508. smp03:    add    eax,128
  509.     mul    byte ptr cs:[edi][ebx+256]
  510.     sub    ecx,eax
  511.  
  512.     mov    eax,ebx            ; ebx = 256 - ebx
  513.     mov    ebx,256
  514.     sub    ebx,eax
  515.  
  516.     mov    al,[esi+1]
  517.     and    eax,0ffH
  518.     cmp    eax,128
  519.     jb    smp04
  520.     mov    edx,eax
  521.     mov    eax,128
  522.     sub    eax,edx
  523. smp04:    add    eax,128
  524.     mul    byte ptr cs:[edi][ebx]
  525.     add    ecx,eax
  526.  
  527.     mov    al,[esi+2]
  528.     and    eax,0ffH
  529.     cmp    eax,128
  530.     jb    smp05
  531.     mov    edx,eax
  532.     mov    eax,128
  533.     sub    eax,edx
  534. smp05:    add    eax,128
  535.     mul    byte ptr cs:[edi][ebx+256]
  536.     sub    ecx,eax
  537.     sub    ecx,128*256
  538.     sar    ecx,8
  539.     mov    eax,ecx
  540.  
  541. smp06:    pop    edi
  542.     pop    esi
  543.     pop    edx
  544.     pop    ecx
  545.     pop    ebx
  546.     ret    
  547.  
  548. smptb    db    255,255,255,254,254,253,253,252
  549.     db    252,251,251,250,249,249,248,248
  550.     db    247,246,246,245,244,244,243,243
  551.     db    242,241,240,240,239,238,238,237
  552.     db    236,236,235,234,233,233,232,231
  553.     db    230,229,229,228,227,226,225,225
  554.     db    224,223,222,221,221,220,219,218
  555.     db    217,216,215,214,214,213,212,211
  556.     db    210,209,208,207,206,205,204,204
  557.     db    203,202,201,200,199,198,197,196
  558.     db    195,194,193,192,191,190,189,188
  559.     db    187,186,185,184,183,182,181,180
  560.     db    179,178,177,176,175,174,172,171
  561.     db    170,169,168,167,166,165,164,163
  562.     db    162,161,160,158,157,156,155,154
  563.     db    153,152,151,150,148,147,146,145
  564.     db    144,143,142,141,139,138,137,136
  565.     db    135,134,133,132,130,129,128,127
  566.     db    126,125,123,122,121,120,119,118
  567.     db    117,115,114,113,112,111,110,108
  568.     db    107,106,105,104,103,101,100,099
  569.     db    098,097,096,094,093,092,091,090
  570.     db    089,087,086,085,084,083,082,080
  571.     db    079,078,077,076,075,073,072,071
  572.     db    070,069,068,067,065,064,063,062
  573.     db    061,060,058,057,056,055,054,053
  574.     db    052,051,049,048,047,046,045,044
  575.     db    043,042,040,039,038,037,036,035
  576.     db    034,033,032,030,029,028,027,026
  577.     db    025,024,023,022,021,020,019,018
  578.     db    016,015,014,013,012,011,010,009
  579.     db    008,007,006,005,004,003,002,001
  580.  
  581.     db    000,000,001,001,001,002,002,002
  582.     db    003,003,003,003,004,004,004,005
  583.     db    005,005,005,006,006,006,006,007
  584.     db    007,007,007,008,008,008,008,009
  585.     db    009,009,009,009,010,010,010,010
  586.     db    010,011,011,011,011,011,011,012
  587.     db    012,012,012,012,012,013,013,013
  588.     db    013,013,013,013,014,014,014,014
  589.     db    014,014,014,014,014,015,015,015
  590.     db    015,015,015,015,015,015,015,015
  591.     db    015,016,016,016,016,016,016,016
  592.     db    016,016,016,016,016,016,016,016
  593.     db    016,016,016,016,016,016,016,016
  594.     db    016,016,016,016,016,016,016,016
  595.     db    016,016,016,016,016,016,016,016
  596.     db    016,016,016,016,016,016,016,016
  597.     db    016,016,016,016,016,016,016,016
  598.     db    016,016,015,015,015,015,015,015
  599.     db    015,015,015,015,015,015,015,015
  600.     db    014,014,014,014,014,014,014,014
  601.     db    014,014,014,013,013,013,013,013
  602.     db    013,013,013,013,012,012,012,012
  603.     db    012,012,012,012,012,011,011,011
  604.     db    011,011,011,011,011,010,010,010
  605.     db    010,010,010,010,009,009,009,009
  606.     db    009,009,009,008,008,008,008,008
  607.     db    008,008,007,007,007,007,007,007
  608.     db    007,006,006,006,006,006,006,005
  609.     db    005,005,005,005,005,004,004,004
  610.     db    004,004,004,003,003,003,003,003
  611.     db    003,002,002,002,002,002,002,001
  612.     db    001,001,001,001,001,000,000,000
  613.  
  614. sndVoiceChange    endp
  615.  
  616. cseg    ends
  617.     end
  618.